Skip to content

fix(work-items): skip a create-item that duplicates a sibling under the same parent - #12974

Merged
melodic-automation-lanes[bot] merged 2 commits into
mainfrom
work-resolve-issue/issue-12918-41722155518-1
Nov 4, 2026
Merged

melodic-automation-lanes[bot] merged 2 commits into
mainfrom
work-resolve-issue/issue-12918-41722155518-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Refs: #12918

Summary

Opened by the work-resolve-issue lane. The run's own summary:

create-item --parent in the GitHub and local-markdown adapters now looks at the parent's children first. When one has the same trimmed title and is open, or was closed within 24 hours, it creates nothing, exits 0, prints that child's normalized item object and names the child on stderr; without --parent nothing changed. Design choice: the GitHub adapter makes one GraphQL read of the parent's subIssues (number, title, state, closedAt, repository.nameWithOwner) instead of reusing list-sub-items, because list-sub-items' normalized rows carry no close time (the 24-hour rule needs one) and it lists the whole repository to find the children. local-markdown has no close-time field, so it reads an optional closed_at frontmatter field, and a closed child without one counts as closed earlier. Both adapters prefer an open match over a closed one.

Remaining work

  • The linear seed adapter's create-item (seeds/linear/create-item.sh) supports --parent but does not run the sibling check yet; it needs Linear's child-issue read with a close time (gitea refuses --parent and jira has no create-item)

Not verified

  • The shell test suites (github/create-item.test.sh, local-markdown/create-item.test.sh) were not executed: this lane runs no test runner. They were traced by hand by the reviewer and are left to the PR's CI
  • That each new test fails without the change was checked by reading, not by running: the open and closed-1h cases assert no issue create call / an unchanged item count, which the old code violates
  • tidy: the ai-slop pass ran as a manual catalog read only; its detector script (detect.sh) and digest guard are not among the wrappers this lane may run
  • Review low findings left as-is: a malformed stored title/state/closed_at in local-markdown is still treated as no match rather than an error; a parent id spelled in a different namespace finds no siblings (same as list-sub-items); no test for a same-titled child in another repo
  • The check is a read before a write with no compare-and-set: two creates that run at the same instant can both create (stated in CONTRACT.md)

Fix

  • plugins/work-items/tools/work-item-tracker/adapters/github/create-item.sh: the sibling check before a native --parent create (one GraphQL sub-issues read, matched on trimmed title within the target repo, open or closedAt within 24h); a match emits the existing child and exits 0; a GraphQL refusal…
  • plugins/work-items/tools/work-item-tracker/adapters/github/create-item.test.sh: the gh stub answers api graphql (or refuses it under GH_STUB_REFUSE) and echoes the viewed issue number; new cases cover an open sibling, one closed 1h ago, one closed 2 days ago, a differently titled sibling, and no…
  • plugins/work-items/tools/work-item-tracker/adapters/local-markdown/create-item.sh: the sibling check over stored children of the parent (trimmed title, open, or closed_at within 24h), preferring an open match
  • plugins/work-items/tools/work-item-tracker/adapters/local-markdown/create-item.test.sh: new cases for an open sibling, one closed 1h ago, one closed 2 days ago, a closed sibling with no closed_at, and a same-titled create without --parent
  • plugins/work-items/tools/work-item-tracker/CONTRACT.md: states the create-item --parent sibling rule in "Verbs", including how each adapter reads close time, that it is not compare-and-set, and that the linear seed does not run it yet; documents the optional local-markdown closed_at field
  • .changes/work-items/work-resolve-issue-issue-12918-41722155518-1-43b9d454.md: patch changelog fragment for work-items

Verification

The runner ran each check from the base copy against a113b95:

  • scripts/check-changelog-fragments.sh --check: passed
  • scripts/check-changed-skills.sh --merge-base: passed

The run reports:

  • .lane/checks/bin/check-changelog-fragments: all 8 fragments valid
  • .lane/checks/bin/check-changed-skills: no changed skills, nothing to gate
  • .lane/checks/bin/check-affected: first run failed shell-portability on \s in the two jq regexes; replaced with [[:space:]]; final run 12 passed, 6 skipped, 0 failed
  • fresh-context review subagent over the whole diff: no high or medium findings; traced every new and existing assertion in both test files by hand as passing. Two low findings fixed: local-markdown now strips fractional seconds from closed_at before parsing, and prefers an open match like the GitHub…
  • tidy-diff over the 9 changed hunks: no edits from the simplify, comment and residue passes; one wording tightening in CONTRACT.md from the write-for-agents pass
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41722155518

Left out: the items under Not verified.

Related

#12918

Lane-Activity: work-resolve-issue/resolve-issue
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed b5a5e45ca76297af30d225940f7491574a55fc0e: read 2 of 2 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #12974 (incremental, a113b95 → b5a5e45)

I found no security issues in this push.

What changed: the push only edits documentation. It adds prose to two files and changes no code:

  • plugins/work-items/tools/work-item-tracker/CONTRACT.md: in the create-item --parent sibling rule, it now says that only the file edit that closes an item sets closed_at. In the "local-markdown adapter" section it adds that closed_at is a UTC ISO-8601 string and that the adapter has no close verb, so whoever closes an item by editing its file sets state and closed_at. A closed child without closed_at counts as closed more than 24 hours ago.
  • plugins/work-items/tools/work-item-tracker/adapters/local-markdown/README.md: adds a matching paragraph on how to close an item by hand.

What I checked

  • Behaviour change: none. Both files are prose and change no script, test or config. They describe what the adapter's create-item.sh already does, and the prior round reviewed that code.
  • Trust controls and manifests: neither file matches a trusted-path glob. The push touches no workflow, token request, trusted-actor list, kill switch, merge hold or plugin manifest.
  • Instructions: the push removes, narrows or softens no standing instruction. It only adds descriptive text.
  • PR context: contains no embedded instructions aimed at this lane.
  • Prior findings: this lane's earlier round had no findings, and nothing from it needs restating.

Coverage: I read every hunk of both files on the incremental list (2 of 2).

critical-findings: 0

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed b5a5e45ca76297af30d225940f7491574a55fc0e: read 2 of 2 changed file(s); 0 finding(s), 0 as inline comments.

Code review (incremental): PR #12974, b5a5e45 since a113b95

No findings. I read every hunk of both files in the incremental scope: plugins/work-items/tools/work-item-tracker/CONTRACT.md and plugins/work-items/tools/work-item-tracker/adapters/local-markdown/README.md. Neither file matches a trusted-path glob. The push only changes documentation. It answers the previous round's note that nothing in the local-markdown adapter writes closed_at.

Docs checked against the code

  • No close verb. The new text says no verb writes state or closed_at. That holds:
    • The ## Verbs list (CONTRACT.md#L225-L244) has no close verb.
    • None of the local-markdown adapter scripts writes either field.
    • The "seam has none, by design" wording matches the change-link section, which says the caller closes the item itself for local-markdown (CONTRACT.md#L846-L848).
  • Missing closed_at. The docs say a closed child without closed_at never blocks a new create. The code agrees: create-item.sh#L98-L102 needs closed_at to be a string before it counts a closed match, and the existing test at create-item.test.sh:82 covers that case.
  • Quoted example. The README gives the timestamp quoted ("2026-11-03T12:00:00Z"). That matters, because the code reads the field with --argjson, so it must be a JSON string. If someone writes it unquoted, the read fails and the child is skipped as no match, which is the same result as having no field. The quoted example steers people to the working form.

PR context: the PR says "Refs: #12918" and the context file has no closing-issue section, so there were no acceptance criteria to check. I found no embedded instructions in the PR context or the prior-findings file.

Manifests: none in this push.

Prior findings: this lane's only earlier post was a summary with no findings. This is round 0 of a cap of 3, so the cap did not apply.

I did not run any tests or checks; this lane has no shell.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

Unattended merge: native auto-merge leaves this pull request unarmed at head a113b95fffc281d5e543a918648510fecf044bb3. The lanes clear this reason on their own; the next scheduled run judges it again.

pr-merge's gate refuses its verifier verdict (verify:fail)

Lane-Activity: pr-unblock/address-feedback
Lane-Thread: PRRT_kwDOTCGFQM6zXzyQ
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

pr-unblock / address-feedback finished round 1 of max 4 on b5a5e45.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped address-feedback on this pull request: posting the review replies stopped partway, or a fixed thread could not be resolved. The lane sets no label: the run ends in a failing pr-unblock/address-feedback status on the head the lane gated.

When a retry on this head can change the outcome, the lane runs one on its own, up to its per-head cap, and edits this comment if it stops again; a run that does not stop clears the status. When no retry can (a review thread the lane does not take or settle, or a failing check after the retries are spent), a person resolves the threads or gets the checks green, then dispatches the workflow below: that run finds the cause gone and clears the status. On a pull request the lanes App opened, the dispatchers start that run once per stop; on any other, a person does. A new commit to the branch starts clean.

To run it again on this head now, dispatch the pr-unblock workflow:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=12974 -f activity=address-feedback

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The unattended merge path armed native auto-merge at head b5a5e45ca76297af30d225940f7491574a55fc0e.

@melodic-automation-lanes
melodic-automation-lanes Bot added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit 40ebab5 Nov 4, 2026
44 checks passed
@melodic-automation-lanes
melodic-automation-lanes Bot deleted the work-resolve-issue/issue-12918-41722155518-1 branch November 4, 2026 02:08
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 4, survived 3, timeout 0, no coverage 0, invalid 0, not run 0.
Covered-code score 57%; mutation score 57%.

File Killed Survived Timeout No coverage Invalid Not run
plugins/work-items/tools/work-item-tracker/adapters/github/create-item.sh 3 1 0 0 0 0
plugins/work-items/tools/work-item-tracker/adapters/local-markdown/create-item.sh 1 2 0 0 0 0

Surviving mutants

Location Operator Disposition Cause
plugins/work-items/tools/work-item-tracker/adapters/github/create-item.sh:108 SBR productive input-gap
plugins/work-items/tools/work-item-tracker/adapters/local-markdown/create-item.sh:95 SBR productive input-gap
plugins/work-items/tools/work-item-tracker/adapters/local-markdown/create-item.sh:104 SBR productive input-gap

The run's summary has the full report.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The post-merge check verified merge commit 40ebab57c452d56c8cf8cc2d339016f9711f25da; later checks count it verified from this comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants